package com.lkd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Strings;
import com.lkd.common.VMSystem;
import com.lkd.entity.OrderCollectEntity;
import com.lkd.entity.OrderEntity;
import com.lkd.service.OrderCollectService;
import com.lkd.service.OrderService;
import com.lkd.service.ReportService;
import com.lkd.vo.BarCharVO;
import com.lkd.vo.Pager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import lombok.var;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {


    @Autowired
    private RestHighLevelClient esClient;

    @Autowired
    private OrderService orderService;

    @Override
    public BarCharVO getCollectByRegion(LocalDate start, LocalDate end) {
        LambdaQueryWrapper<OrderEntity> queryWrapper = Wrappers.lambdaQuery(OrderEntity.class).between(OrderEntity::getCreateTime, start, end)
                .eq(OrderEntity::getPayStatus, VMSystem.PAY_STATUS_PAYED);
        List<OrderEntity> list = orderService.list(queryWrapper);
        BarCharVO barCharVO = new BarCharVO();
        Map<String, List<OrderEntity>> map = list.stream().collect(Collectors.groupingBy(OrderEntity::getRegionName));
        for (Map.Entry<String, List<OrderEntity>> entry : map.entrySet()) {
            String key = entry.getKey();
            int count=0;
            List<OrderEntity> countList = entry.getValue();
            for (OrderEntity orderEntity : countList) {
                count+= orderEntity.getAmount();
            }
            barCharVO.getXAxis().add(key);
            barCharVO.getSeries().add(count);
        }
        return barCharVO;
    }


    @Autowired
    private OrderCollectService orderCollectService;


    @Override
    public Pager<OrderCollectEntity> getPartnerCollect(Long pageIndex, Long pageSize, String name, LocalDateTime start, LocalDateTime end) {

        Page<OrderCollectEntity> page = new Page<>(pageIndex,pageSize);

        QueryWrapper<OrderCollectEntity> queryWrapper = new QueryWrapper<>();

        //select查询指定字段
        // IFNULL() 函数用于判断第一个表达式是否为 NULL，如果为 NULL 则返回第二个参数的值，如果不为 NULL 则返回第一个参数的值
        queryWrapper.select("IFNULL(sum(order_count),0) as order_count"
                ,"IFNULL(sum(total_bill),0) as total_bill"
                ,"IFNULL(sum(order_total_money),0) as order_total_money"
                ,"IFNULL(min(ratio),0) as ratio","owner_name","date");

        //用户有输入合作商查询
        if(!StringUtils.isEmpty(name)){
            queryWrapper.lambda().like(OrderCollectEntity::getOwnerName,name);
        }


        //用户根据时间来查询
        queryWrapper.lambda().ge(OrderCollectEntity ::getDate,start )
                .le(OrderCollectEntity::getDate,end)
                .groupBy(OrderCollectEntity::getDate,OrderCollectEntity::getOwnerName)
                .orderByDesc(OrderCollectEntity::getDate);
        return Pager.build(orderCollectService.page(page,queryWrapper));
    }


    @Override
    public List<OrderCollectEntity> getTop12(Integer partnerId) {

        return null;
    }

    /**
     * 合作商搜索分账信息
     * @param partnerId
     * @param pageIndex
     * @param pageSize
     * @param nodeName
     * @param start
     * @param end
     * @return
     */
    @Override
    public Pager<OrderCollectEntity> search(Long pageIndex, Long pageSize, Integer partnerId, String nodeName, LocalDate start, LocalDate end) {
        var qw = new LambdaQueryWrapper<OrderCollectEntity>();
        qw
                .select(OrderCollectEntity::getDate, OrderCollectEntity::getNodeName, OrderCollectEntity::getOrderCount, OrderCollectEntity::getTotalBill)
                .eq(OrderCollectEntity::getOwnerId, partnerId);
        if (!Strings.isNullOrEmpty(nodeName)) {
            qw.like(OrderCollectEntity::getNodeName, nodeName);
        }
        if (start != null && end != null) {
            qw
                    .ge(OrderCollectEntity::getDate, start)
                    .le(OrderCollectEntity::getDate, end);
        }
        qw.orderByDesc(OrderCollectEntity::getDate);
        var page = new Page<OrderCollectEntity>(pageIndex, pageSize);
        return Pager.build(orderCollectService.page(page, qw));
    }


    @Override
    public BarCharVO getCollect(Integer partnerId, LocalDate start, LocalDate end) {

        BarCharVO barCharVO = new BarCharVO();
        //1.首先根据条件获取数据
        QueryWrapper<OrderCollectEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .select("IFNULL(sum(total_bill),0) as total_bill", "date")
                .lambda()
                .eq(OrderCollectEntity::getOwnerId, partnerId)
                .ge(OrderCollectEntity::getDate, start)
                .le(OrderCollectEntity::getDate, end)
                .groupBy(OrderCollectEntity::getDate)
                .orderByDesc(OrderCollectEntity::getDate);

        List<OrderCollectEntity> list = orderCollectService.list(queryWrapper);
        //转化为时间和金额的map集合
        Map<LocalDate, Integer> collect = list.stream().collect(Collectors.toMap(OrderCollectEntity::getDate, OrderCollectEntity::getTotalBill));
        //获取给定端点之间的日期流
        start.datesUntil(end.plusDays(1), Period.ofDays(1))
                .forEach(date->{
                    barCharVO.getXAxis().add(date.format(DateTimeFormatter.ISO_LOCAL_DATE));
                    //判断map集合是否含有对应的使时间key
                    if(collect.containsKey(date)){
                        barCharVO.getSeries().add(collect.get(date));
                    }else {
                        barCharVO.getSeries().add(0);
                    }
                });

        return barCharVO;
    }

}
